// <com.woyouqiu.Copyright>
// --------------------------------------------------------------
// <copyright>上海有求网络科技有限公司 2015</copyright>
// <Solution>MyCompany.MyProject</Solution>
// <Project>MyCompany.MyProject.Application</Project>
// <FileName>ProductCategoryAppService.cs</FileName>
// <CreateTime>2017-04-18 0:01</CreateTime>
// <Author>何苗</Author>
// <Email>hemiao@woyouqiu.com</Email>
// <log date="2017-04-18 0:01" version="00001">创建</log>
// --------------------------------------------------------------
// </com.woyouqiu.Copyright>

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Collections.Extensions;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.UI;
using Vecen.BangChuang.BangChuang.DomainServices.Products;
using Vecen.BangChuang.BangChuang.Products.Dto;

namespace Vecen.BangChuang.BangChuang.Products {
    /// <summary>
    /// 
    /// </summary>
    public class ProductCategoryAppService: BangChuangAppServiceBase, IProductCategoryAppService {
        private readonly IRepository<ProductCategory> _productCategoryRepository;
        private readonly ProductCategoryDomainService _productCategoryDomainService;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="productCategoryRepository"></param>
        /// <param name="productCategoryDomainService"></param>
        public ProductCategoryAppService(IRepository<ProductCategory> productCategoryRepository,
            ProductCategoryDomainService productCategoryDomainService) {
            _productCategoryRepository = productCategoryRepository;
            _productCategoryDomainService = productCategoryDomainService;
        }

        /// <summary>
        /// 获得所有商品分类
        /// </summary>
        /// <returns></returns>
        public async Task<ListResultDto<CategoryOutputDto>> GetCategoriesAsync(GetCategoriesRequestDto input)
        {
            var query = _productCategoryRepository.GetAll()
                .Where(c => c.ProductType == input.ProductType.ToString())
                .WhereIf(!input.ParentFullCode.IsNullOrEmpty(), c => c.FullCode.StartsWith(input.ParentFullCode))
                .WhereIf(input.ParentId.HasValue, c => c.ParentId == input.ParentId);
            var entities = await Task.Run(() => query.ToList());
            var list = new List<CategoryOutputDto>();
            foreach (var category in entities)
            {
                var dto = category.MapTo<CategoryOutputDto>();
                dto.ProductCount =
                    await _productCategoryDomainService.GetProductCountByCategoryIdAsync(category.Id);
                list.Add(dto);
            }
            return new ListResultDto<CategoryOutputDto>(list);
        }

        /// <summary>
        /// 以树形结果获取所有商品分类
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public Task<CategoryTreeDto> GetCategoriesWithTreeAsync(GetCategoriesRequestDto input) {
            return Task.Run(() => {
                var entities =
                    _productCategoryRepository.GetAll()
                        .WhereIf(!input.ParentFullCode.IsNullOrEmpty(), c => c.FullCode.StartsWith(input.ParentFullCode))
                        .WhereIf(input.ParentId.HasValue, c => c.ParentId == input.ParentId)
                        .ToList();
                return FillingTree(null, entities);
            });
        }

        /// <summary>
        /// 创建分类
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [AbpAuthorize]
        public async Task CreateAsync(CategoryCreateDto input) {
            if(input.ParentId.HasValue) {
                if(await _productCategoryRepository.FirstOrDefaultAsync(input.ParentId.Value) == null) {
                    throw new UserFriendlyException("请求失败!", "要保存分类的父节点不存在");
                }
            }
            if(_productCategoryRepository.GetAll()
                .Where(c => c.ParentId == input.ParentId)
                .Any(c => c.Name == input.Name)) {
                throw new UserFriendlyException("请求失败!", "同级节点名称不能相同!");
            }

            await _productCategoryRepository.InsertOrUpdateAndGetIdAsync(new ProductCategory()
                {Name = input.Name, ParentId = input.ParentId,ProductType = ProductType.Jewelry.ToString()});
        }

        private CategoryTreeDto FillingTree(CategoryTreeDto parentDto, IEnumerable<ProductCategory> entities) {
            var children = entities.ToList();
            if(parentDto == null) {
                children = children.Where(c => c.ParentId == null).ToList();
                parentDto = new CategoryTreeDto();
                parentDto.Id = 0;
                parentDto.Name = "Root";
                parentDto.Children = new List<CategoryTreeDto>();
            } else {
                children = children.Where(c => c.ParentId == parentDto.Id).ToList();
            }

            foreach(var productCategory in children) {
                var childDto = new CategoryTreeDto();
                childDto.FullCode = productCategory.FullCode;
                childDto.Name = productCategory.Name;
                childDto.Id = productCategory.Id;
                childDto.Children = new List<CategoryTreeDto>();
                FillingTree(childDto, entities);
                parentDto.Children.Add(childDto);
            }

            return parentDto;
        }

        /// <summary>
        /// 删除分类
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [AbpAuthorize]
        public async Task DeleteAsync(int id) {
            await _productCategoryDomainService.DeleteAsync(id);
        }
    }
}